#!/usr/bin/env python
# -*- coding:utf-8 -*-
from sys import argv
from time import strftime
from lib.request.ragent import *
from lib.utils.printer import *
import os

#软件信息
VERSION = "V3.0.0.1"
AUTHOR = "kail"
DESCRIPTION = "web漏洞扫描器"

#基础路径配置
ROOT_NAME = "scan://"
ROOT_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../../")#项目路径
PLUGIN_PATH = os.path.join(ROOT_PATH,"plugins")#插件路径
LIB_PATH = os.path.join(ROOT_PATH,"lib")#核心库路径
DB_PATH = os.path.join(LIB_PATH,"db")#字典路径
REPORT_PATH = os.path.join(ROOT_PATH,"report")#测试报告路径

#db配置
ERRORS_PATH = os.path.join(DB_PATH,'errors')
SQLDBERRORS_PATH = os.path.join(DB_PATH,"sqldberror")
PHPINFO_PATH = os.path.join(DB_PATH,"phpinfo.txt")
ADMINPANEL_PATH = os.path.join(DB_PATH,"adminpanel.txt")
BACKDOOR_PATH = os.path.join(DB_PATH,"backdoor.txt")
BACKUPDIR_PATH = os.path.join(DB_PATH,"backupdir.txt")
COMMONFILE_PATH = os.path.join(DB_PATH,"commonfile.txt")
PARAMS_PATH = os.path.join(DB_PATH,"params.txt")
#测试报告配置
REPORT_JSON = os.path.join(REPORT_PATH,"json")
REPORT_HTML = os.path.join(REPORT_PATH,"html")
REPORT_CSSJS = os.path.join(REPORT_PATH,"cssjs")

#插件配置
##集成检测注入漏洞模块,相关的注入性漏洞放在这里
P_ATTACKS_PATH = os.path.join(PLUGIN_PATH,"attacks")
##集成检测默认配置漏洞，中间件配置相关的漏洞放在这里,中间件[Apache,weblogic,Tomcat,nginx,iis等]
P_AUDIT_PATH = os.path.join(PLUGIN_PATH,"audit")
##集成检测蛮力猜解模块,例如猜解后台管理地址、敏感的备份文件等
P_BRUTE_PATH = os.path.join(PLUGIN_PATH,"brute")
##集成检测页面或响应内容中的敏感信息等
P_DISCOSURE_PATH = os.path.join(PLUGIN_PATH,"disclosure")

#插件模块信息
##插件描述
plugs_info ={
    'attacks':"注入漏洞插件集合",
    'audit':'中间件相关漏洞插件集合',
    'brute':'蛮力猜解插件集合',
    'disclosure':"敏感信息检测插件集合"
}
plugs = {
    '1':'attacks',
    '2':'audit',
    '3':'brute',
    '4':'disclosure',
    '5':'fullscan'
}

#注入漏洞检测配置 attacks
##描述
attacks_info = {
    'bashi':"检测bashi命令注入,破壳漏洞(ShellShock)",
    'blindsqli':"检测SQL盲注",
    'bufferoverflow':'检测缓冲区溢出检测',
    'crlf':"检测crlf注入 即回车换行注入",
    'headersqli':"HTTP的头信息header,检测是否可能存在sql注入漏洞",
    'headerxss':"检测Headers头信息中XSS漏洞",
    'htmli':"检测html代码注入",
    'ldapi':"检测LDAP[轻量级目录访问协议]注入",
    'lfi':"检测本地文件包含漏洞",
    'oscommand':"检测操作系统命令注入漏洞",
    'phpi':"检测PHP代码注入漏洞",
    'sqli':"检测SQL注入漏洞",
    'ssi':"检测服务端包含注入漏洞",
    'xpathi':"检测xpath[xml路径语言]注入漏洞",
    'xss':"检测XSS跨站点脚本漏洞",
    'xxe':"检测XXE XML外部实体注入漏洞",
    'xst':"#检测XST跨站跟踪漏洞"
}
##插件路径
attacks = {
    #检测bash命令注入,破壳漏洞(ShellShock)
    'bashi': P_ATTACKS_PATH + os.sep + 'bashi.py',
    #检测SQL盲注
    'blindsqli':P_ATTACKS_PATH + os.sep + 'blindsqli.py',
    #检测缓冲区溢出检测
    'bufferoverflow':P_ATTACKS_PATH + os.sep + 'bufferoverflow.py',
    #检测crlf注入 即回车换行注入
    'crlf':P_ATTACKS_PATH + os.sep + 'crlf.py',
    #HTTP的头信息header,检测是否可能存在sql注入漏洞
    'headersqli':P_ATTACKS_PATH + os.sep + 'headersqli.py',
    #检测Headers头信息中XSS漏洞
    'headerxss':P_ATTACKS_PATH + os.sep + 'headerxss.py',
    #检测html代码注入
    'htmli':P_ATTACKS_PATH + os.sep + 'htmli.py',
    #检测LDAP[轻量级目录访问协议]注入
    'ldapi':P_ATTACKS_PATH + os.sep + 'ldapi.py',
    #检测本地文件包含漏洞
    'lfi':P_ATTACKS_PATH + os.sep + 'lfi.py',
    #检测操作系统命令注入漏洞
    'oscommand':P_ATTACKS_PATH + os.sep + 'oscommand.py',
    #检测PHP代码注入漏洞
    'phpi':P_ATTACKS_PATH + os.sep + 'phpi.py',
    #检测SQL注入漏洞
    'sqli':P_ATTACKS_PATH + os.sep + 'sqli.py',
    #检测服务端包含注入漏洞
    'ssi':P_ATTACKS_PATH + os.sep + 'ssi.py',
    #检测xpath[xml路径语言]注入漏洞
    'xpathi':P_ATTACKS_PATH + os.sep + 'xpathi.py',
    #检测XSS跨站点脚本漏洞
    'xss':P_ATTACKS_PATH + os.sep + 'xss.py',
    #检测XXE XML外部实体注入漏洞
    'xxe':P_ATTACKS_PATH + os.sep + 'xxe.py',
    #检测XST跨站跟踪漏洞
    'xst':P_ATTACKS_PATH + os.sep + 'xst.py'
}
#中间件相关漏洞配置 audit
##描述
audit_info = {
    'apache':"检测Apache相关配置页面",
    'phpinfo':"检测phpinfo页面",
    'robots': "检测robots.txt"
}
##插件路径
audit = {
    #检测Apache相关配置页面
    'apache': P_AUDIT_PATH + os.sep + 'apache.py',
    #检测phpinfo页面
    'phpinfo': P_AUDIT_PATH + os.sep + 'phpinfo.py',
    #检测robots.txt
    'robots': P_AUDIT_PATH + os.sep + 'robots.py'
}
#蛮力猜解插件配置 brute
##描述
brute_info = {
    'adminpanel':"猜解可能的管理页面",
    'backdoor':"检测可能的后门程序",
    'backupdir':"检测可能的备份目录",
    'commondir':"检测可能的通用目录，附带敏感信息检测",
    'commonfile':"检测可能的敏感文件",
    'params':"检测可能的隐藏参数"
}
##插件路径
brute = {
    #猜解可能的管理页面
    'adminpanel': P_BRUTE_PATH + os.sep + 'adminpanel.py',
    #检测可能的后门程序
    'backdoor': P_BRUTE_PATH + os.sep + 'backdoor.py',
    #检测可能的备份目录
    'backupdir': P_BRUTE_PATH + os.sep + 'backupdir.py',
    #检测可能的通用目录，附带敏感信息检测
    'commondir': P_BRUTE_PATH + os.sep + 'commondir.py',
    #检测可能的敏感文件
    'commonfile': P_BRUTE_PATH + os.sep + 'commonfile.py',
    #检测可能的隐藏参数
    'params': P_BRUTE_PATH + os.sep + 'params.py'

}
#正则匹配
REG_EMAIL = r'[a-zA-Z0-9.\-_+#~!$&\',;=:]+@+[a-zA-Z0-9-]*\.\w*'
REG_IP = r'[0-9]+(?:\.[0-9]+){3}'
REG_DOMAIN = r'^([a-zA-Z0-9]([a-zA-Z0-9-_]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,11}$'
REG_DOMAIN_L = r'^[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+(:[0-9]{1,5})?[-a-zA-Z0-9()@:%_\\\+\.~#?&//=]*$'
REG_URL = r'^(http(s)?:\/\/)\w+[^\s]+(\.[^\s]+){1,}$'
REG_ERRORS =(
    "<font face=\"Arial\" size=2>error \'800a0005\'</font>",
    "<h2> <i>Runtime Error</i> </h2></span>",
    "<p>Active Server Pages</font> <font face=\"Arial\" size=2>error \'ASP 0126\'</font>",
    "<b> Description: </b>An unhandled exception occurred during the execution of the",
    "<H1>Error page exception</H1>",
    "<h2> <i>Runtime Error</i> </h2></span>",
    "<h2> <i>Access is denied</i> </h2></span>",
    "<H3>Original Exception: </H3>",
    "Server object error",
    "invalid literal for int()",
    "exceptions.ValueError",
    "\[an error occurred while processing this directive\]",
    "<HTML><HEAD><TITLE>Error Occurred While Processing Request</TITLE>",
    "</HEAD><BODY><HR><H3>Error Occurred While Processing Request</H3><P>",
    "\[java.lang.",
    "class java.lang.",
    "java.lang.NullPointerException",
    "java.rmi.ServerException",
    "at java.lang.",
    "onclick=\"toggle(\'full exception chain stacktrace\')",
    "at org.apache.catalina",
    "at org.apache.coyote.",
    "at org.apache.tomcat.",
    "at org.apache.jasper.",
    "<html><head><title>Application Exception</title>",
    "<p>Microsoft VBScript runtime </font>",
    "<font face=\"Arial\" size=2>error '800a000d'</font>",
    "<TITLE>nwwcgi Error",
    "\] does not contain handler parameter named",
    "PythonHandler django.core.handlers.modpython",
    "t = loader.get_template(template_name) # You need to create a 404.html template.",
    "<h2>Traceback <span>(innermost last)</span></h2>",
    "<h1 class=\"error_title\">Ruby on Rails application could not be started</h1>",
    "<title>Error Occurred While Processing Request</title></head><body><p></p>",
    "<HTML><HEAD><TITLE>Error Occurred While Processing Request</TITLE></HEAD><BODY><HR><H3>",
    "<TR><TD><H4>Error Diagnostic Information</H4><P><P>",
    "<li>Search the <a href=\"http://www.macromedia.com/support/coldfusion/\"",
    "target=\"new\">Knowledge Base</a> to find a solution to your problem.</li>",
    "Server.Execute Error",
    "<h2 style=\"font:8pt/11pt verdana; color:000000\">HTTP 403.6 - Forbidden: IP address rejected<br>",
    "<TITLE>500 Internal Server Error</TITLE>",
    "<b>warning</b>[/]\w\/\w\/\S*",
    "<b>Fatal error</b>:",
    "<b>Warning</b>:",
    "open_basedir restriction in effect",
    "eval()'d code</b> on line <b>",
    "Fatal error</b>:  preg_replace",
    "thrown in <b>",
    "Stack trace:",
    "</b> on line <b>"
)
#敏感信息检测模块配置
##描述
disclosure_info = {
    'emails':"检测页面Email信息",
    'findip':"检测页面IP信息",
    'errors':"检测错误响应页面中的敏感信息"
}
##插件路径
disclosure = {
    #检测页面Email信息
    'emails': P_DISCOSURE_PATH + os.sep + 'emails.py',
    #检测页面IP信息
    'findip': P_DISCOSURE_PATH + os.sep + 'findip.py',
    #检测错误响应页面中的敏感信息
    'errors': P_DISCOSURE_PATH + os.sep + 'errors.py'
}
#加载注入漏洞插件
def attacks_plugins():
    _plugins = []
    for root,dirs,files in os.walk(P_ATTACKS_PATH):
        files = filter(lambda x: not x.startswith("__") 
        and x.endswith(".py"),files)
        _plugins.extend(map(lambda x: os.path.join(root,x),files))
    return _plugins
def spec_attacks_plugins(key:str):
    _plugin = []
    if key in attacks.keys():
        _plugin.append(attacks[key])
    return _plugin
#加载审计漏洞插件
def audit_plugins():
    _plugins = []
    for root,dirs,files in os.walk(P_AUDIT_PATH):
        files = filter(lambda x: not x.startswith("__") 
        and x.endswith(".py"),files)
        _plugins.extend(map(lambda x: os.path.join(root,x),files))
    return _plugins
def spec_audit_plugins(key:str):
    _plugin = []
    if key in audit.keys():
        _plugin.append(audit[key])
    return _plugin
#加载蛮力猜解插件
def brute_plugins():
    _plugins = []
    for root,dirs,files in os.walk(P_BRUTE_PATH):
        files = filter(lambda x: not x.startswith("__") 
        and x.endswith(".py"),files)
        _plugins.extend(map(lambda x: os.path.join(root,x),files))
    return _plugins
def spec_brute_plugins(key:str):
    _plugin = []
    if key in brute.keys():
        _plugin.append(brute[key])
    return _plugin
#加载敏感信息检测插件
def disclosure_plugins():
    _plugins = []
    for root,dirs,files in os.walk(P_DISCOSURE_PATH):
        files = filter(lambda x: not x.startswith("__") 
        and x.endswith(".py"),files)
        _plugins.extend(map(lambda x: os.path.join(root,x),files))
    return _plugins
def spec_disclosure_plugins(key:str):
    _plugin = []
    if key in disclosure.keys():
        _plugin.append(disclosure[key])
    return _plugin
#参数设置 kwargs

ARGV = {
    'url':None,
    'scan':None,
    'auth': None,
    'brute': None,
    'agent': ragent().decode('utf-8'),
    'proxy': None,
    'pauth': None,
    'cookie': None,
    'timeout': 5,
    'redirect': True,
    'headers': {},
    'data': None,
    'method': 'GET'
}
#线程数
T_MAX = 5
#当前时间
NOW = strftime("%H:%M:%S")
TIME = strftime('%d/%m/%Y at %H:%M:%S')
#测试报告配置
REPORT = {
    'fileName':None,
    'name':None,
    'title':None,
    'startTime':None,
    'execmod':[],
    'total':None,
    'successTotal':None,
    'failTotal':None,
    'attacks':{},
    'audit':{},
    'brute':{},
    'disclosure':{}

}
